package com.sxt.service.impl;

import com.sxt.entity.Order;
import com.sxt.entity.OrderItem;
import com.sxt.entity.OrderSettlement;
import com.sxt.mapper.OrderItemMapper;
import com.sxt.mapper.OrderMapper;
import com.sxt.mapper.OrderSettlementMapper;
import com.sxt.model.ShopCartItem;
import com.sxt.model.WechatMsg;
import com.sxt.service.BasketService;
import com.sxt.service.OrderService;
import com.sxt.service.ProdService;
import com.sxt.service.SkuService;
import com.sxt.vo.order.OrderVo;

import cn.hutool.json.JSONUtil;
import lombok.extern.slf4j.Slf4j;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatterBuilder;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.jms.JMSException;
import javax.jms.Message;

import org.apache.activemq.ScheduledMessage;
import org.apache.dubbo.config.annotation.Reference;
import org.apache.dubbo.config.annotation.Service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.format.datetime.DateFormatter;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.jms.core.MessagePostProcessor;
import org.springframework.transaction.annotation.Transactional;

/**
 * <p>
 * 订单表 服务实现类
 * </p>
 *
 * @author liangtiandong
 * @since 2019-12-17
 */
@Service
@Slf4j
public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements OrderService {

	private static SimpleDateFormat SDF = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
	@Reference(check = false)
	private BasketService basketService ;

	@Reference(check = false)
	private ProdService prodService ;

	@Reference(check = false)
	private SkuService skuService ;

	@Autowired
	private JmsTemplate jmsTemplate ;

	@Autowired
	private OrderMapper orderMapper ;

	@Autowired 
	private OrderItemMapper orderItemMapper ;

	@Autowired 
	private OrderSettlementMapper orderSettlementMapper ;

	@Transactional
	@Override
	public void createPreOrder(OrderVo orderVo) {
		log.info("开始下单{}",JSONUtil.toJsonPrettyStr(orderVo));
		// 本次要购买的条目
		List<ShopCartItem> cartItems = orderVo.getShopCartOrders().get(0).getShopCartItemDiscounts().get(0).getShopCartItems();
		// 1 清空购物车  protal-api
		basketService.clearCart(cartItems);
		// 2 扣减库存 // item-api
		prodService.decsStock(cartItems) ;
		skuService.decrStock(cartItems) ;
		// 3 搜索引擎的销量 //search-api（使用mq 交互）
//		jmsTemplate.convertAndSend("order.decr.stock", cartItems);
		// 4 写订单表 //本地写
		writeOrderAndItemAndSettlement(orderVo);

		// 5延迟消息 // 在本地发
		// 发送个字符串之后，它就是文本消息，这样因为convert 导致，它内部有消息转化器（SimpleMessageConverter），能识别 instance of你放的类型
		jmsTemplate.convertAndSend("order.delay.queue", orderVo.getOrderSn(),new MessagePostProcessor() {
			// 延迟消息
			@Override
			public Message postProcessMessage(Message message) throws JMSException {
				message.setLongProperty(ScheduledMessage.AMQ_SCHEDULED_DELAY, 10*1000 ); // 10s的延迟 30*60*10000
				return message;
			}
		});
		// 6 通知用户下单成功 // 最后在本地做
		sendOrderMsgToUser(orderVo);
//		int i = 10 / 0  ;
	}

	private void writeOrderAndItemAndSettlement(OrderVo orderVo) {
		List<ShopCartItem> orderProd = orderVo.getShopCartOrders().get(0).getShopCartItemDiscounts().get(0).getShopCartItems();
		StringBuilder sb = new StringBuilder() ;

		// 订单和商品的中间表
		for (ShopCartItem shopCartItem : orderProd) {
			sb.append(shopCartItem.getProdName()).append(",") ;
			OrderItem orderItem = shopCartItem2OrderItem(shopCartItem,orderVo.getOrderSn()) ;
			orderItemMapper.insert(orderItem) ;
		}
		// 订单表
		Order order = builderOrder(orderVo, sb);
		orderMapper.insert(order);

		// 订单的结算表
		OrderSettlement orderSettlement = new OrderSettlement();
		orderSettlement.setPayAmount(orderVo.getActualTotal()) ;
		orderSettlement.setOrderNumber(orderVo.getOrderSn()) ;
		orderSettlement.setPayType(2) ;
		orderSettlement.setPayTypeName("支付宝支付");
		orderSettlement.setCreateTime(LocalDateTime.now()) ;
		orderSettlement.setIsClearing(0) ;// 没有支付
		orderSettlement.setPayStatus(0) ;

		orderSettlementMapper.insert(orderSettlement) ;


	}

	private Order builderOrder(OrderVo orderVo, StringBuilder sb) {
		Order order = new Order();
		order.setOrderNumber(orderVo.getOrderSn()) ;// 上一步使用雪花算法生成的编号
		order.setUserId(orderVo.getUserAddr().getUserId()) ;
		order.setProductNums(orderVo.getTotalCount());
		order.setActualTotal(orderVo.getActualTotal()); //
		order.setTotal(orderVo.getTotal()) ;
		order.setCreateTime(LocalDateTime.now()) ;
		order.setIsPayed(false) ;
		//  @ApiModelProperty(value = "订单状态 1:待付款 2:待发货 3:待收货 4:待评价 5:成功 6:失败")
		order.setStatus(1) ;
		order.setDeleteStatus(0)  ;
		order.setDvyType("商家配送") ;
		order.setFreightAmount(orderVo.getShopCartOrders().get(0).getTransfee()) ;
		order.setReduceAmount(orderVo.getShopCartOrders().get(0).getShopReduce()) ;
		order.setProdName(sb.deleteCharAt(sb.length()-1).toString()) ;// 多个商品使用， 隔开
		return order;
	}

	private OrderItem shopCartItem2OrderItem(ShopCartItem shopCartItem, String orderSn) {
		OrderItem orderItem = new OrderItem();
		// order
		orderItem.setOrderNumber(orderSn) ;
		// prod
		orderItem.setProdId(shopCartItem.getProdId()) ;
		orderItem.setSkuId(shopCartItem.getSkuId()) ;
		orderItem.setSkuName(shopCartItem.getSkuName()) ;
		orderItem.setPic(shopCartItem.getPic()) ;
		orderItem.setPrice(shopCartItem.getPrice()) ;
		orderItem.setProdCount(shopCartItem.getProdCount()) ;
		orderItem.setProdName(shopCartItem.getProdName()) ;
		orderItem.setRecTime(LocalDateTime.now()) ;
		orderItem.setShopId(1l) ;
		orderItem.setProductTotalAmount(shopCartItem.getPrice().multiply(new BigDecimal(shopCartItem.getProdCount()))) ;
		return orderItem;
	}

	private void sendOrderMsgToUser(OrderVo orderVo) {
		System.out.println("给用户发送消息，说下单成功了，赶紧去付钱");
		WechatMsg wechatMsg = new WechatMsg();
		/**
		 * 微信小程序中心 openiD
		 * 微信公众号 OPENID 
		 * 用户的openId 不是小程序的openId ，是公众号的openId
		 * ，你需要引导用户关注你的公众号才可以！
		 * 
		 */
		wechatMsg.setToUser("op16B0zbY0O-uMAMz1XVFE0yDxYI"); // 要动态的获取一个用户的实际的id
		wechatMsg.setTemplateId("zUu_LG6ACZlcXInkIiMB0yExhrhhKZmVe_NrwYIMxq8");
		wechatMsg.setTopColor("#0099FF");
		wechatMsg.setUrl("https://www.ego.shop/order/"+orderVo.getOrderSn());
		Map<String, Map<String, String>> data = new HashMap<String,Map<String,String>>();
		data.put("orderSn", WechatMsg.builde("【ego商城】："+orderVo.getOrderSn(), "#0099FF"));
		data.put("totalMoney", WechatMsg.builde(orderVo.getTotal().toString(), "#0099FF"));
		data.put("orderDate", WechatMsg.builde(SDF.format(new Date()), "#0099FF")) ;
		wechatMsg.setData(data);
		jmsTemplate.convertAndSend("wechat.msg.queue", wechatMsg);
	}

}
